using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using Decav.Gatsb.Application;
using Decav.Gatsb.Web;
using Decav.Gatsb;
using Decav.Gatsb.Data;
using System.Collections.Generic;
using System.Text;

public partial class Home : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        GatsbWebApplication.EnsureAuthenticatedSession();
        SetBasicInfo();
        
        if (!IsPostBack)
            SetFriendsRecentLocations();

        SetIncompleteLocationStatus();

        if (GatsbWebApplication.Current.NewAccountHasNotSeenHelp)
        {
            suggestGettingStarted.Visible = true;
        }

        ((IMasterPageTemplate)Master).SelectedPage = MainMenuNavigationButton.Home;

        InitializeRecent();
    }

    private void SetBasicInfo()
    {
        usernameLiteral.Text = GatsbApplication.Current.CurrentUser.Name.FirstName;

        if (HttpContext.Current.Session["Homepage_Status"] != null)
        {
            string message = (string)HttpContext.Current.Session["Homepage_Status"];
            HttpContext.Current.Session["Homepage_Status"] = null;

            serverStatus.InnerHtml = message;
            serverStatus.Visible = true;
        }
        else
        {
            serverStatus.Visible = false;
        }

        if (UserStatus.InboxMessageCount > 0)
        {
            inboxStatus.Visible = true;
            inboxStatus.InnerHtml = string.Format("<a href=\"Inbox.aspx\">You have {0} messages in your inbox.</a>", UserStatus.InboxMessageCount);
        }
        else
        {
            inboxStatus.Visible = false;
        }
    }

    private Dictionary<Guid, int> _pushpinIndicies = new Dictionary<Guid, int>();

    protected void InitializeRecent()
    {
        Decav.Gatsb.Post[] items = null;

        using (IGatsbDataAdapter adapt = GatsbApplication.Current.GetDataAdapter())
            items = adapt.GetLatestPosts(false, true, 15);

        recentHappenings.DataSource = items;
        recentHappenings.Visible = items.Length > 0;
        noRecentHappeningsDiv.Visible = items.Length == 0;
        if (items.Length > 0)
            recentHappenings.DataBind();
    }

    protected int GetLocationPushpinIndex(Guid locationId)
    {
        int i = 0;
        if (_pushpinIndicies.TryGetValue(locationId, out i))
            return i;
        else
            return 6;
    }

    private void SetFriendsRecentLocations()
    {
        LocationCheckin[] checkins = null;
        using (IGatsbDataAdapter adapt = GatsbApplication.Current.GetDataAdapter())
            checkins = adapt.GetLatestCheckins();

        if (checkins.Length == 0)
        {
            recentEventRepeater.Visible = false;
            noRecentEventsDiv.Visible = true;
        }
        else
        {
            recentEventRepeater.Visible = true;
            noRecentEventsDiv.Visible = false;

            Dictionary<Guid, List<LocationCheckin>> pins = new Dictionary<Guid, List<LocationCheckin>>();

            // Group checkins by location so that we can show one pin per location.
            foreach (LocationCheckin checkin in checkins)
            {
                List<LocationCheckin> pinItems = null;
                if (!pins.TryGetValue(checkin.Location.Id, out pinItems))
                {
                    pinItems = new List<LocationCheckin>();
                    pins.Add(checkin.Location.Id, pinItems);
                }

                pinItems.Add(checkin);
            }

            int i = 1;
            foreach (KeyValuePair<Guid, List<LocationCheckin>> pin in pins)
            {
                // Don't show temporary location's pushpins.
                if (pin.Value[0].Location.Temporary)
                    continue;

                MapPushpin pushpin = new MapPushpin(pin.Key,
                    pin.Value[0].Location.Name,
                    pin.Value[0].Location.GeographicCoordinates);

                _pushpinIndicies.Add(pin.Key, Math.Min(i, 6));
                
                StringBuilder builder = new StringBuilder();
                builder.Append("<ul>");
                foreach (LocationCheckin checkin in pin.Value)
                    builder.AppendFormat("<li><a href=\"Person.aspx?id={0}\">{1}</a> ({2})</li>",
                        checkin.User.Id, checkin.User.Name.FirstName,
                        StringFormatting.ToTimeAgo(checkin.CheckinDate));
                builder.Append("</ul>");

                pushpin.DetailHtml = builder.ToString();

                friendMap.Pushpins.Add(pushpin);
                i++;
            }

            for (int k = 0; k<checkins.Length; k++)
            {
                LocationCheckin checkin = checkins[k];
                if (checkin.LocationSpecified && !checkin.Location.Temporary)
                {
                    friendMap.MapCenter = checkin.Location.GeographicCoordinates;
                    break;
                }
            }
        }

        recentEventRepeater.DataSource = checkins;
        recentEventRepeater.DataBind();
    }

    private void SetIncompleteLocationStatus()
    {
        int count = 0;
        using (IGatsbDataAdapter adapt = GatsbApplication.Current.GetDataAdapter())
            count = adapt.GetUserIncompleteLocations().Length;

        if (count == 0)
        {
            incompleteLocationStatus.Visible = false;
            return;
        }

        incompleteLocationStatus.Visible = true;
        incompleteLocationStatus.InnerHtml =
            string.Format("You checked into {0} that Gatsb was confused about.  <a href=\"ClarifyLocations.aspx\">Please clarify {1} now</a>.",
                (count == 1) ? "a place" : string.Format("{0} places", count),
                (count == 1) ? "this place" : "these places");
    }

    protected string GetLocationJavascript(Location location)
    {
        if (location.Temporary)
        {
            return string.Format("alert(\"This location is new and doesn't have an address yet.\");return false;");
        }
        else
        {
            return string.Format("CenterMap({0}, {1});return false;", location.GeographicCoordinates.Latitude, location.GeographicCoordinates.Longitude);
        }
    }

    public UserStatusInfo UserStatus
    {
        get
        {
            if (_status == null)
                _status = GatsbApplication.Current.GetStatus();

            return _status;
        }
    }

    private UserStatusInfo _status;
}
